package com.quanyan.platform.wrapper.impl;

import com.alibaba.dubbo.common.utils.CollectionUtils;
import com.alibaba.fastjson.JSON;
import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.club.entity.RespPlaceClubInfo;
import com.quanyan.comment.reqeust.ReqUserCollectQuery;
import com.quanyan.comment.serviceFacade.UserCollectServiceFacade;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.utils.GsonUtils;
import com.quanyan.place.client.PlaceClient;
import com.quanyan.place.entity.PlaceDubboProvider;
import com.quanyan.platform.cache.MyRedisTemplate;
import com.quanyan.platform.constant.PlatformConstants;
import com.quanyan.platform.model.db.TbCircle;
import com.quanyan.platform.model.db.TbCirclePlaceRelation;
import com.quanyan.platform.model.resp.GatheringPlaceResponse;
import com.quanyan.platform.response.GatherPlaceResponse;
import com.quanyan.platform.service.ICirclePlaceService;
import com.quanyan.platform.service.IplaceService;
import com.quanyan.platform.wrapper.IGatheringPlace;
import com.quanyan.user.response.RespPlaceVideoInfo;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Created by jingliu on 17/3/13.
 */
@Service
public class GatheringPlaceImpl implements IGatheringPlace {
	private static final Logger logger = LoggerFactory.getLogger(GatheringPlaceImpl.class);
	@Autowired
	ICirclePlaceService circlePlaceService;
	@Autowired
	IplaceService iPlaceDubboService;
	private ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	@Autowired
	private PlaceClient placeClient;
	@Autowired
	private UserCollectServiceFacade userCollectServiceFacade;
	@Autowired
	private MyRedisTemplate myRedisTemplate;

	@Override
	public APIResponse<?> findGatheringPlace(@NotNull Integer circleId, @NotNull final Integer categoryId, @NotNull Integer uid, Double lat, Double lng) {
		List<GatheringPlaceResponse> gatheringPlaceResponses = new ArrayList<>();
		final List<Integer> placeIds = new ArrayList<>();
		List<Integer> placeIdList = (List<Integer>) myRedisTemplate.get(PlatformConstants.getCircleReportKey(circleId, categoryId));
		logger.info("从缓存中获取的推荐场馆--Cache：{};circleId：{}；categoryId：{}",GsonUtils.toJson(placeIdList),circleId,categoryId);
		if (placeIdList == null) {
			TbCirclePlaceRelation tbCirclePlaceRelation = new TbCirclePlaceRelation();
			tbCirclePlaceRelation.setCircleId(circleId);
			tbCirclePlaceRelation.setCategoryId(categoryId);
			tbCirclePlaceRelation.setIsReport(PlatformConstants.REPORT_PLACE);
			List<TbCirclePlaceRelation> tbCirclePlaceRelations = circlePlaceService.findTbCirclePlaceRelations(tbCirclePlaceRelation);
			placeIdList = new ArrayList<>();
			for (TbCirclePlaceRelation tbCirclePlaceRelationModel : tbCirclePlaceRelations) {
				placeIdList.add(tbCirclePlaceRelationModel.getPlaceId());
			}
			myRedisTemplate.setValueAndExpire(PlatformConstants.getCircleReportKey(circleId, categoryId),placeIdList,43200);
		}

		placeIds.addAll(placeIdList);

		if (CollectionUtils.isEmpty(placeIds)) {
			return APIResponse.returnFail(ApiResponseEnum.RECORD_DO_NOT_EXISTS);
		}

		// 调用场馆对应视频
		long videoStartTime = System.currentTimeMillis();
		logger.info("开始获取推荐场馆视频——ONE:请求参数：{}；开始时间：{}", GsonUtils.toJson(placeIds), videoStartTime);
		Future<Object> videoFuture = pool.submit(new Callable<Object>() {

			@Override
			public Object call() {
				try {
					return iPlaceDubboService.getPlaceVideoInfo(placeIds);
				} catch (Exception e) {
					logger.error("调用场馆对应视频异常:{}", e);
					return null;
				}
			}
		});
		// 调用场馆对应俱乐部
		long clubStartTime = System.currentTimeMillis();
		logger.info("开始获取推荐场馆俱乐部——TWO:请求参数：{}；开始时间：{}", GsonUtils.toJson(placeIds), clubStartTime);
		Future<Object> clubFuture = pool.submit(new Callable<Object>() {
			@Override
			public Object call() {
				try {
					return iPlaceDubboService.selectClubByPlaceIds(placeIds, Constants.DEFAULT_PAGE_INDEX,
							Constants.DEFAULT_PAGE_INDEX, categoryId);
				} catch (Exception e) {
					logger.error("调用场馆对应俱乐部异常:{}", e);
					return null;
				}
			}
		});

		//调用场馆对应俱乐部活动
		long activityStartTime = System.currentTimeMillis();
		logger.info("开始获取推荐场馆活动——THREE:请求参数：{}；开始时间：{}", GsonUtils.toJson(placeIds), activityStartTime);
		Future<Object> clubActivityFuture = pool.submit(new Callable<Object>() {
			@Override
			public Object call() {
				try {
					return iPlaceDubboService.selectActivityByPlaceIds(placeIds, Constants.DEFAULT_PAGE_INDEX,
							Constants.DEFAULT_PAGE_INDEX, categoryId);
				} catch (Exception e) {
					logger.error("调用场馆对应俱乐部活动异常:{}", e);
					return null;
				}
			}
		});
		// 调用达人
		long talentStartTime = System.currentTimeMillis();
		logger.info("开始获取推荐场馆达人——FOUR:请求参数：{}；开始时间：{}", GsonUtils.toJson(placeIds), talentStartTime);
		Future<Object> masterFuture = pool.submit(new Callable<Object>() {
			@Override
			public Object call() {
				try {
					return iPlaceDubboService.getMasterByPlaceIds(placeIds, Constants.DEFAULT_PAGE_NUM,
							Constants.DEFAULT_PAGE_INDEX);
				} catch (Exception e) {
					logger.error("调用场馆对应俱乐部活动异常:{}", e.getMessage());
					return null;
				}
			}
		});

		Map<Integer, RespPlaceVideoInfo> videoInfoMap;

		try {
			videoInfoMap = (Map<Integer, RespPlaceVideoInfo>) videoFuture.get();
			long videoEndTime = System.currentTimeMillis();
			logger.info("获取推荐场馆视频返回结果-ONE：{}；返回时间：{}，接口调用时长：{}", GsonUtils.toJson(videoInfoMap), videoEndTime, videoEndTime - videoStartTime);
		} catch (Exception e) {
			logger.error("场馆聚集地视频异常{}", e);
			return APIResponse.returnFail(String.format("场馆聚集地视频异常%s", e.getMessage()));
		}

		Map<Integer, List<RespPlaceClubInfo>> clubInfoMap;

		try {
			clubInfoMap = (Map<Integer, List<RespPlaceClubInfo>>) clubFuture.get();
			long clubEndTime = System.currentTimeMillis();
			logger.info("获取推荐场馆俱乐部返回结果-TWO：{}；返回时间：{}，接口调用时长：{}", GsonUtils.toJson(clubInfoMap), clubEndTime, clubEndTime - clubStartTime);
		} catch (Exception e) {
			logger.error("场馆聚集地俱乐部异常{}", e);
			return APIResponse.returnFail(String.format("场馆聚集地俱乐部异常%s", e.getMessage()));
		}
		Map<Integer, List<RespPlaceClubInfo>> clubActivityMap;

		try {
			clubActivityMap = (Map<Integer, List<RespPlaceClubInfo>>) clubActivityFuture.get();
			long activityEndTime = System.currentTimeMillis();
			logger.info("获取推荐场馆活动返回结果-THREE：{}；返回时间：{}，接口调用时长：{}", GsonUtils.toJson(clubActivityMap), activityEndTime, activityEndTime - activityStartTime);
		} catch (Exception e) {
			logger.error("场馆聚集地俱乐部活动异常{}", e);
			return APIResponse.returnFail(String.format("场馆聚集地俱乐部活动异常%s", e.getMessage()));
		}

		Map<Integer, GatherPlaceResponse> masterMap;

		try {
			masterMap = (Map<Integer, GatherPlaceResponse>) masterFuture.get();
			long talentEndTime = System.currentTimeMillis();
			logger.info("获取推荐场馆达人返回结果-FOUR：{}；返回时间：{}，接口调用时长：{}", GsonUtils.toJson(masterMap), talentEndTime, talentEndTime - talentStartTime);
		} catch (Exception e) {
			logger.error("场馆聚集地达人异常{}", e);
			return APIResponse.returnFail(String.format("场馆聚集地达人异常%s", e.getMessage()));
		}

		Map<Integer, PlaceDubboProvider> map;
		try {
			map = placeClient.getPlaceByTerm(placeIds, lat, lng);
			logger.info("Map<Integer, PlaceDubboProvider> map:{}", JSON.toJSONString(map));
			if (MapUtils.isEmpty(map)) {
				return APIResponse.returnFail("调用场馆服务查询无结果");
			}
		} catch (Exception e) {
			logger.error("调用场馆服务异常:{}", e);
			return APIResponse.returnFail(String.format("场馆信息获取异常%s", e.getMessage()));
		}

		try {
			GatheringPlaceResponse gatheringPlaceResponse = null;
			for (Integer placeid : placeIds) {
				gatheringPlaceResponse = new GatheringPlaceResponse();
				PlaceDubboProvider placeDubboProvider = map.get(placeid);
				if (null == placeDubboProvider) {
					logger.error("没有此场馆信息placeid:{}", placeid);
					continue;
				}
				//调用是否收藏过
				if (0 != uid) {
					try {
						ReqUserCollectQuery reqUserCollect = new ReqUserCollectQuery();
						reqUserCollect.setSystemCode(Constants.PLACE_SYSTEM_CODE);
						reqUserCollect.setBusinessCode(Constants.PLACE_BOOKING_CODE);
						reqUserCollect.setUserId(uid);
						reqUserCollect.setBusinessId(placeid);
						APIResponse<Boolean> colresponse = userCollectServiceFacade.isUserCollect(reqUserCollect);
						logger.info("调用场馆收藏返回结果：{}", GsonUtils.toJson(colresponse));
						if (null != colresponse && colresponse.isRet() && null != colresponse.getData()) {
							int iscollect = colresponse.getData() ? 0 : 1;
							placeDubboProvider.setIsCollect(iscollect);
						}
					} catch (Exception e) {
						logger.error("调用收藏服务异常:{}", e);
					}
				}

				gatheringPlaceResponse.setPlaceDubboProvider(placeDubboProvider);
				gatheringPlaceResponse
						.setRespPlaceVideoInfo(MapUtils.isEmpty(videoInfoMap)
								? new RespPlaceVideoInfo() : videoInfoMap.get(placeid));
				gatheringPlaceResponse
						.setRespPlaceClubInfo(CollectionUtils.isEmpty(clubInfoMap.get(placeid))
								? new RespPlaceClubInfo() : clubInfoMap.get(placeid).get(0));
				gatheringPlaceResponse
						.setRespActivityClubInfo(CollectionUtils.isEmpty(clubActivityMap.get(placeid))
								? new RespPlaceClubInfo() : clubActivityMap.get(placeid).get(0));
				gatheringPlaceResponse
						.setGatherPlaceResponse(MapUtils.isEmpty(masterMap)
								? new GatherPlaceResponse() : masterMap.get(placeid));
				gatheringPlaceResponses.add(gatheringPlaceResponse);
			}
		} catch (Exception e) {
			logger.error("聚集地场馆返回异常:{}", e);
		}
		logger.info("List<GatheringPlaceResponse>:{}", JSON.toJSONString(gatheringPlaceResponses));
		return APIResponse.returnSuccess(gatheringPlaceResponses);
	}
}
